﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Web;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;
using RedFoxUtils;

namespace RedFoxSpamKiller
{
  public sealed class Forum
  {
    private static Dictionary<string, string> boardMapping = new Dictionary<string, string>
    {
      {"1","http://fox.hanyu.com.tw/View.aspx?fbId=1&Id=51299"},
      {"2","http://fox.hanyu.com.tw/View.aspx?fbId=2&Id=21406"},
      {"12","http://fox.hanyu.com.tw/View.aspx?fbId=12&Id=50648"},
      {"3","http://fox.hanyu.com.tw/View.aspx?fbId=3&Id=51305"},
      {"7","http://fox.hanyu.com.tw/View.aspx?fbId=7&Id=51552"},
      {"8","http://fox.hanyu.com.tw/View.aspx?fbId=8&Id=28131"},
      {"10","http://fox.hanyu.com.tw/View.aspx?fbId=10&Id=50875"},
      {"11","http://fox.hanyu.com.tw/View.aspx?fbId=11&Id=51553"},
      {"9","http://fox.hanyu.com.tw/View.aspx?fbId=9&Id=51554"},
      {"6","http://fox.hanyu.com.tw/View.aspx?fbId=6&Id=51555"},
      {"5","http://fox.hanyu.com.tw/View.aspx?fbId=5&Id=51556"},
      {"4","http://fox.hanyu.com.tw/View.aspx?fbId=4&Id=2323"}
    };

    /// <summary>
    /// Posts article to board.
    /// </summary>
    /// <param name="fbid">The fbid.</param>
    /// <param name="message">The message.</param>
    /// <returns></returns>
    public static bool PostToBoard(string fbid, string message)
    {
      string url="";
      if (!boardMapping.TryGetValue(fbid, out url))
        return false;
      return Post(url, "公告-"+DateTime.Now.ToShortDateString(), message);
    }

    /// <summary>
    /// Posts article according to the specified URL.
    /// </summary>
    /// <param name="url">The URL.</param>
    /// <param name="title">The title.</param>
    /// <param name="body">The body.</param>
    /// <returns></returns>
    public static bool Post(string url, string title, string body)
    {
      try
      {
        Uri uri = new Uri(url);
        var httpClient = new HttpClient(Helper.GetUriCookieContainer(uri));
        Stream data = httpClient.OpenRead(uri);
        StreamReader reader = new StreamReader(data, Encoding.GetEncoding(950));
        string srcString = reader.ReadToEnd();
        data.Close();
        reader.Close();

        //Get the ViewState
        string viewStateFlag = "id=\"__VIEWSTATE\" value=\"";
        int i = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;
        int j = srcString.IndexOf("\"", i);
        string viewState = srcString.Substring(i, j - i);
        //Debug.WriteLine("viewState={0}", viewState);

        //Get the ViewState
        string EventValidationFlag = "id=\"__EVENTVALIDATION\" value=\"";
        i = srcString.IndexOf(EventValidationFlag) + EventValidationFlag.Length;
        j = srcString.IndexOf("\"", i);
        string eventValidation = srcString.Substring(i, j - i);
        //Debug.WriteLine("eventValidation={0}", eventValidation);

        //Compose the URL
        viewState = Uri.EscapeDataString(viewState);
        eventValidation = Uri.EscapeDataString(eventValidation);

        string formatString = "__VIEWSTATE={0}&__EVENTVALIDATION={1}&sTitle={2}&sBody={3}&SaveIt={4}";
        string postString = string.Format(formatString,
          viewState,
          eventValidation,
          Helper.unicode2EncodedBig5(title),
          Helper.unicode2EncodedBig5(body),
          Helper.unicode2EncodedBig5("OK發表我的回應貼子")
          );

        Debug.WriteLine(postString);

        //Change to byte[]
        byte[] postData = Encoding.ASCII.GetBytes(postString);

        httpClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
        // 上傳數據，返回頁面的字節數組
        byte[] responseData = httpClient.UploadData(uri, "POST", postData);

        srcString = Encoding.GetEncoding(950).GetString(responseData);
        if (srcString.IndexOf("帖子存檔成功!") > 0 && srcString.IndexOf("發表成功") > 0)
          return true;
        Debug.WriteLine("找不到成功的訊息，請檢查。{0}",srcString);
        return false;
      }
      catch (WebException we)
      {
        Debug.WriteLine(we.Message);
      }
      catch (Exception ex)
      {
        Debug.WriteLine(ex.Message);
      }
      return false;
    }

    /// <summary>
    /// Gets the web page.
    /// </summary>
    /// <param name="uri">The URI.</param>
    /// <returns></returns>
    private static string GetWebPage( Uri uri )
    {
      var httpClient = new HttpClient(Helper.GetUriCookieContainer(uri));
      Stream data = httpClient.OpenRead(uri);
      StreamReader reader = new StreamReader(data, Encoding.GetEncoding(950));
      string content = reader.ReadToEnd();
      data.Close();
      reader.Close();
      return content;
    }

    /// <summary>
    /// 根據 RSS feed 取出文章。
    /// </summary>
    /// <returns></returns>
    public static List<Post> CheckRSSFeed(decimal count)
    {
      Uri uri = new Uri(String.Format("http://fox.hanyu.com.tw/rss.aspx?count={0}", count));
      string xml = GetWebPage(uri);

      List<Post> posts = new List<Post>();

      XmlDocument doc = new XmlDocument();
      try
      {
        doc.LoadXml(xml);
      }
      catch (XmlException ex)
      {
        Debug.WriteLine(ex.Message);
        doc = null;
      }
      if (doc == null)
      {
        return posts;
      }
      var query = from n in doc.SelectNodes("rss/channel/item").Cast<XmlNode>()
                  select n;
      foreach (XmlNode node in query)
      {
        // Please refer to XMLFile1.xml
        // [0] title
        // [1] link
        // [2] guid
        // [3] category
        // [4] pubDate
        // [5] description
        // [6] author
        // [7] comment
        posts.Add(new Post(node.ChildNodes[0].InnerText,
          node.ChildNodes[2].InnerText,
          node.ChildNodes[6].InnerText));
      }

      return posts;
    }

    /// <summary>
    /// Deletes the specified post.
    /// </summary>
    /// <param name="uri">The URI.</param>
    /// <returns></returns>
    public static bool DeletePost(Uri uri)
    {
      string s = GetWebPage(uri);
      //Debug.WriteLine(s);
      return true;
    }

    /// <summary>
    /// Deletes the post accoring to the string contained URL.
    /// </summary>
    /// <param name="url">The URL.</param>
    /// <returns></returns>
    public static bool DeletePost( string url )
    {
      return DeletePost(new Uri(url));
    }

    /// <summary>
    /// Parses the link and return a tuple..
    /// </summary>
    /// <param name="link">The link.</param>
    /// <returns>A tuple, first item is forum's id, 2nd item is article id.</returns>
    public static Tuple<string, string> ParseLink(string link)
    {
      var r = new Regex(@"(?<1>\w+)=(?<2>\d*)", RegexOptions.Compiled);
      var m = r.Match(link);
      string fbId = "", id = "";
      while (m.Success)
      {
        Debug.WriteLine(m.Groups.Count);
        Debug.WriteLine(m.Groups[0].Value + '|' + m.Groups[1].Value + '|' + m.Groups[2].Value);
        switch (m.Groups[1].Value)
        {
          case "fbId":
            fbId = m.Groups[2].Value;
            break;
          case "Id":
            id = m.Groups[2].Value;
            break;
        }
        m = m.NextMatch();
      }

      if (String.IsNullOrEmpty(fbId) || String.IsNullOrEmpty(id))
      {
        throw new Exception("fbId or id is empty or null.");
      }
      return new Tuple<string, string>(fbId, id);
    }

    /// <summary>
    /// 根據網址產生可以刪除文章的網址
    /// </summary>
    /// <param name="link"></param>
    /// <returns></returns>
    public static string GenerateRemoveLink(string link)
    {
      Tuple<string, string> tuple = ParseLink(link);
      return string.Format("http://fox.hanyu.com.tw/Admin_Action.aspx?Action=Del&fbId={0}&Id={1}", tuple.Item1, tuple.Item2);
    }
  }
}
